import {EventEmitter, Injectable} from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { NzMessageService } from 'ng-zorro-antd/message';
import {LocalStorageService} from '../share/local-storage.service';
import {Subscription} from 'rxjs';

interface AjaxHeaderInterface {
  'cache-control': string;
  'Content-Type': string;
  responseType: string;
  'xylo-token': string;
}

interface AjaxConfigInterface {
  url: string;
  data: any;
  type: 'get' | 'post';
  success: any;
  failed: any;
  async?: boolean;
  headers?: any;
}

@Injectable({
  providedIn: 'root'
})

export class GlobalAjaxService {
  public isLoadingData = [];
  public isTokenInvalid = new EventEmitter();
  constructor(
    private http: HttpClient,
    private message: NzMessageService,
    private localStorage: LocalStorageService
  ) {}

  /**
   * @description 公共请求
   */
  public request(config: AjaxConfigInterface): Subscription{
    this.isLoadingData.push(1);
    const header = this.getJsonHeader(config.headers);
    const url = $_serverPath + config.url + `?v=${+new Date()}`;
    const requestType = config.type;
    const options: any = {
      params: config.data,
      headers: header
    }
    return this.http.request(requestType, url, options).subscribe( (res: any) => {
      if (res.code === 200) {
        config.success(res);
      } else {
        config.failed(res);
        this.message.create('error', res.message || 'Unknown exception!');
      }
      this.isLoadingData.pop();
    }, (data) => {
      const err = data.error;
      if (err.code === 401) {
        this.isTokenInvalid.emit();
      }
      config.failed(err);
      this.message.create('error', err.message || 'Unknown exception');
      this.isLoadingData.pop();
    });
  }

  private getJsonHeader(configHeader: object): object {
    const defaultHeader: AjaxHeaderInterface = {
      'Content-Type': 'application/json',
      'cache-control': 'no-cache',
      responseType: 'json',
      'xylo-token': this.localStorage.get($_xyloToken)
    };
    Object.assign(defaultHeader, configHeader || {});
    const httpHeaders = new HttpHeaders();
    const keys = Object.keys(defaultHeader);
    for (const key of keys) {
      httpHeaders.set(key, defaultHeader[key]);
    }
    return defaultHeader;
  }
}
